﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

using NetDon.OA.Interface;
using NetDon.eBoss.Data.CollectionClasses;
using NetDon.eBoss.Data.EntityClasses;
using NetDon.eBoss.Data.HelperClasses;
using NetDon.eBoss.Data.Linq;
using SD.LLBLGen.Pro.ORMSupportClasses;  

namespace NetDon.OA.Business
{
    public class DictionaryService : CategoryCachableService<DictionaryData>, IDictionaryService, IDictionaryManageService
    {
        private readonly DictionaryCategoryService _categoryService = new DictionaryCategoryService();
        public DictionaryService()
            : base("DataDictionary")
        {
        }

        private class DictionaryCategoryService : PrimitiveCachableService<DictionaryCategory>
        {
            public DictionaryCategoryService()
                : base("DictionaryCategory")
            {
            }

            private DictionaryCategory GetDictionaryCategory(DictionarycategoryEntity category)
            {
                return new DictionaryCategory
                           {
                               CategoryId = category.Oid,
                               CategoryName = category.Name
                           };
            }

            #region Overrides of CachableServiceBase<DictionaryCategory>

            protected override DictionaryCategory OnLoadData(object key, ITransaction transaction)
            {
                var session = new LinqMetaData(transaction);
                var query = from dicType in session.Dictionarycategory
                            where dicType.Oid == (int)key
                            select dicType;
                var list = query.ToList();
                if (list.Count > 0)
                {
                    return GetDictionaryCategory(list[0]);
                }
                return null;
            }

            protected override object GetDataKey(DictionaryCategory data)
            {
                return data.CategoryId;
            }

            #endregion

            public IEnumerable<DictionaryCategory> GetCategories()
            {
                return GetAllData();
            }

            #region Overrides of PrimitiveCachableService<DictionaryCategory>

            protected override IEnumerable<DictionaryCategory> OnLoadAllData(ITransaction transaction)
            {
                var session = new LinqMetaData(transaction);
                var query = from dicType in session.Dictionarycategory
                            select dicType;
                return query.ToList().Select(category => GetDictionaryCategory(category));
            }

            #endregion
        }

        /// <summary>
        /// 根据类型获取所有的数据字典项。
        /// </summary>
        /// <param name="categoryId">类型。</param>
        /// <returns></returns>
        public virtual IEnumerable<DictionaryData> GetDataItems(int categoryId)
        {
            return GetCategoryData(categoryId);
        }


        public virtual IEnumerable<DictionaryData> GetDataItems(string typeName)
        {
            IEnumerable<DictionaryCategory> categories = GetCategories();
            foreach (var c in categories)
            {
                if (c.CategoryId.ToString().Trim() == typeName.Trim() || c.CategoryName.Trim() == typeName.Trim())
                {
                    return GetDataItems(c.CategoryId);
                }
            }
            return null;
        }

    

        public virtual IEnumerable<DictionaryCategory> GetCategories()
        {
            return _categoryService.GetCategories();
        }

        public virtual int? GetDictionaryDataByName(string name)
        {
            var meta = new LinqMetaData();
            return (from entity in meta.Dictionary
                    where entity.Name == name.Trim()
                    select entity).FirstOrDefault().Fieldvalue;
        }


        /// <summary>
        /// 根据数据字典项的值获取名称。
        /// </summary>
        /// <param name="categoryId">类型。</param>
        /// <param name="value">数据字典项的值。</param>
        /// <returns>数据字典项的名称。</returns>
        public virtual string GetDataName(int value)
        {
            var entry = GetDataItem(value);
            return entry == null ? null : entry.Name;
        }
        public virtual int? GetDataFieldValue(int? value)
        {
            if (!value.HasValue)
            {
                return value;
            }
            var meta = new LinqMetaData();
            return (from entity in meta.Dictionary
                    where entity.Oid == value
                    select entity).FirstOrDefault().Fieldvalue;
        }
        public DictionaryData GetDataItem(int value)
        {
            return GetData(value);
        }

        /// <summary>
        /// 新增数据字典项。
        /// </summary>
        /// <param name="categoryId">类型。</param>
        /// <param name="name">数据字典项的名称。</param>
        /// <returns>新增的数据字典项的值。</returns>
        public virtual DictionaryData AddEntry(int categoryId, string name)
        {
            var entry = new DictionaryData
            {
                Name = name,
                CategoryId = categoryId

            };
            if (AddData(entry))
            {
                return entry;
            }
            return null;
        }

        /// <summary>
        /// 修改数据字典项的名称。
        /// </summary>
        /// <param name="entry">字典项</param>
        /// <returns>是否修改成功。</returns>
        public virtual Boolean ModifyEntry(DictionaryData entry)
        {
            return ModifyData(entry.Value, entry);
        }

        public virtual Boolean MoveUpEntry(int categoryId, int value)
        {
            return MoveupData(GetDataItem(value));
        }

        public virtual Boolean MoveDownEntry(int categoryId, int value)
        {
            return MovedownData(GetDataItem(value));
        }

        /// <summary>
        /// 移除数据字典项。
        /// </summary>
        /// <param name="categoryId">类型。</param>
        /// <param name="value">数据字典项的值。</param>
        /// <returns>移除是否成功。</returns>
        public virtual Boolean RemoveEntry(int categoryId, int value)
        {
            return RemoveData(value);
        }

        private DictionaryData GetEntry(DictionaryEntity dictionary)
        {
            return new DictionaryData
                       {
                           Index = dictionary.Index,
                           Name = dictionary.Name,
                           CategoryId = dictionary.Typeid,
                           Value = dictionary.Oid,
                           FieldValue = dictionary.Fieldvalue
                       };
        }

        #region Overrides of CachableServiceBase<DictionaryData>

        protected override DictionaryData OnLoadData(object key, ITransaction transaction)
        {
            var session = new LinqMetaData(transaction);
            var query = from dictionary in session.Dictionary
                        where dictionary.Oid == (int)key
                        select dictionary;
            var list = query.ToList();
            if (list.Count > 0)
            {
                return GetEntry(list[0]);
            }
            return null;
        }

        protected override bool OnAddData(DictionaryData data, ITransaction transaction)
        {
            var entries = GetDataItems(data.CategoryId);
            int maxIndex = entries.Count() > 0 ? entries.Max(entry => entry.Index) : -1;
            var entity = new DictionaryEntity
                             {
                                 Name = data.Name,
                                 Typeid = data.CategoryId,
                                 Index = maxIndex + 1,
                                 Fieldvalue = data.FieldValue
                             };
            transaction.Add(entity);
            if (entity.Save())
            {
                data.Index = entity.Index;
                data.Value = entity.Oid;
                return true;
            }
            return false;
        }

        protected override bool OnModifyData(object key, DictionaryData data, ITransaction transaction)
        {
            var entity = new DictionaryEntity();
            transaction.Add(entity);
            entity.FetchUsingPK((int)key);
            if (entity.IsNew)
            {
                return false;
            }
            entity.Name = data.Name;
            return entity.Save();
        }

        protected override bool OnRemoveData(object key, DictionaryData data, ITransaction transaction)
        {
            var collection = new DictionaryCollection();
            transaction.Add(collection);
            return collection.DeleteMulti(DictionaryFields.Oid == (int)key) > 0;
        }

        protected override object GetDataKey(DictionaryData data)
        {
            return data.Value;
        }

        #endregion

        #region Overrides of CategoryCachableService<DictionaryData>

        protected override bool Sortable
        {
            get
            {
                return true;
            }
        }

        protected override int GetSortIndex(DictionaryData data)
        {
            return data.Index;
        }

        protected override IEnumerable<DictionaryData> OnLoadCategoryData(object category, ITransaction transaction)
        {
            var session = new LinqMetaData(transaction);
            var query = from dictionary in session.Dictionary
                        where dictionary.Typeid == (int)category
                        select dictionary;
            return query.ToList().Select(dictionary => GetEntry(dictionary));
        }

        protected override bool ExchangeIndex(DictionaryData x, DictionaryData y)
        {
            ITransaction transaction = new Transaction(IsolationLevel.ReadCommitted, Guid.NewGuid().ToString());
            try
            {
                var collection = new DictionaryCollection();
                var entityX = new DictionaryEntity {Index = x.Index};
                var entityY = new DictionaryEntity {Index = y.Index};
                transaction.Add(collection);
                collection.UpdateMulti(entityY, DictionaryFields.Oid == x.Value);
                collection.UpdateMulti(entityX, DictionaryFields.Oid == y.Value);
                transaction.Commit();
                var index = x.Index;
                x.Index = y.Index;
                y.Index = index;
                return true;
            }
            catch (Exception)
            {
                transaction.Rollback();
                throw;
            }
        }

        protected override object GetCategory(DictionaryData data)
        {
            return data.CategoryId;
        }

        #endregion
    }
}